package com.example.myproject.jackson;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;

import java.io.IOException;

/**
 * Created by xi on 2018/9/21.
 * BeanDeserializer
 * 参考NumberDeserializers 这个实现类
 */
public class JacksonDoubleDeSerializer extends NewPrimitiveOrWrapperDeserializer<Double> {
        private static final long serialVersionUID = 1L;
        public JacksonDoubleDeSerializer(){this(Double.TYPE, null);};
        public JacksonDoubleDeSerializer(Class<Double> cls, Double nvl) {
            super(cls, nvl, null);
        }

        // since 2.6, slightly faster lookups for this very common type
        @Override
        public boolean isCachable() { return true; }

    @Override
    public Double deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        return _parseDouble(p, ctxt);
    }

    // Since we can never have type info ("natural type"; String, Boolean, Integer, Double):
    // (is it an error to even call this version?)
    @Override
    public Double deserializeWithType(JsonParser p, DeserializationContext ctxt,
                                      TypeDeserializer typeDeserializer) throws IOException
    {
        return _parseDouble(p, ctxt);
    }
    protected final Double _parseDouble(JsonParser p, DeserializationContext ctxt) throws IOException
    {
        JsonToken t = p.getCurrentToken();
        if (t == JsonToken.VALUE_NUMBER_INT || t == JsonToken.VALUE_NUMBER_FLOAT) { // coercing should work too
            return p.getDoubleValue();
        }
        if (t == JsonToken.VALUE_STRING) {
            String text = p.getText().trim();
            if ((text.length() == 0)) {
                return (Double) UpdateSpecialConstant.DOBULE_SPECAIL_VALUE;
            }
            if (_hasTextualNull(text)) {
                return (Double) _coerceTextualNull(ctxt, _primitive);
            }
            switch (text.charAt(0)) {
                case 'I':
                    if (_isPosInf(text)) {
                        return Double.POSITIVE_INFINITY;
                    }
                    break;
                case 'N':
                    if (_isNaN(text)) {
                        return Double.NaN;
                    }
                    break;
                case '-':
                    if (_isNegInf(text)) {
                        return Double.NEGATIVE_INFINITY;
                    }
                    break;
            }
            _verifyStringForScalarCoercion(ctxt, text);
            try {
                return parseDouble(text);
            } catch (IllegalArgumentException iae) { }
            return (Double) ctxt.handleWeirdStringValue(_valueClass, text,
                    "not a valid Double value");
        }
        if (t == JsonToken.VALUE_NULL) {
            return (Double) _coerceNullToken(ctxt, _primitive);
        }
        if (t == JsonToken.START_ARRAY) {
            return _deserializeFromArray(p, ctxt);
        }
        // Otherwise, no can do:
        return (Double) ctxt.handleUnexpectedToken(_valueClass, p);
    }
}
